/**
 * 裁剪
 */
export const clipvolume = {
  _inputEvents: {},
  //累计距离
  _cumdistance: 0,//米 延长距离
  //let _tblrdistance = 0;//米 东南西北
  _minclipaltitude: 1,//米 最低裁切海拔
  _nowclipdistance: 1,//米 当前裁切距离
  _maxclipaltitude: 800,//米 最高裁切海拔
  //裁切立体 集合
  ClipCubeCollection: {},
  _clippolygonCollection: {},
  //需要裁切的对象
  _ClipEObject: null,
  //创建裁剪
  createdClip ( opt ) {
    //剪切实体
    let ClipFlag = {
      0: SSmap.ClipVolumeFlag.ClipAll,//裁切所有
      1: SSmap.ClipVolumeFlag.ClipGlobe,//裁切球体
      2: SSmap.ClipVolumeFlag.ClipScene//裁切场景
    }
    //裁切体限制
    var objectnum = Object.getOwnPropertyNames( this.ClipCubeCollection ).length
    if ( objectnum >= 8 ) {
      console.error( 'RangeError :', 'Maximum call ClipVolume value exceeded' )
      return
    }
    //相同id 不同重复创建
    if ( this.ClipCubeCollection[opt.entityid] ) {
      console.error( 'RuntimeError :', 'An ClipVolume with id ' + opt.entityid + ' already exists in this collection.' )
      return
    }
    opt = opt || {}
    let cv = new SSmap.ClipVolume()
    //console.log('cv',cv);
    cv.shape = SSmap.ClipVolumeShape.Cube //剪切形状, 默认Cube立方体 Cylinder
    cv.clipFlag = ClipFlag[opt.flag || 0] //默认是全部剪切, 可选ClipGlobe只裁切球体, ClipScene只裁切场景, ClipAll
    let clipwidth = opt.clipwidth || 100//宽度 默认100
    let cliplength = opt.cliplength || 100//长度 默认100
    let clipheight = opt.clipheight || 1//高度 默认1
    cv.size = SSmap.Vector3.create( clipwidth / 2, cliplength / 2, clipheight / 2 ) // clipwidth x cliplength x
                                                                                     // clipheight 米的剪切体
    cv.showDebugVolume = opt.contour == undefined ? true : opt.contour //是否显示剪切的轮廓
    cv.objectName = opt.name || this._getentityid() //添加一个名称标识
    let nowentity = new SSmap.Entity()
    let rotations = null
    if ( opt.rotations ) {
      rotations = SSmap.Quaternion.fromEulerAngles( opt.rotations[0], opt.rotations[1], opt.rotations[2] )
    } else {
      rotations = SSmap.Quaternion.fromEulerAngles( 0, 0, 0 )
    }
    nowentity.transform.cartographic = opt.centerc //坐标点
    let nowchildEntity = new SSmap.Entity() //子物体
    nowchildEntity.parent = nowentity //设置父子结构
    nowchildEntity.transform.rotation = rotations //旋转角度(四元数)
    nowchildEntity.id = opt.Eclipid || this._getentityid()
    nowchildEntity.addComponent( cv ) //添加组件
    window.GlobalViewer.scene.addEntity( nowentity ) //添加到rootEntity的子节点中
    this.ClipCubeCollection[opt.Eclipid] = {
      clipvolume: cv,
      entity: nowentity,
      childEntity: nowchildEntity,
      type: opt.cliptype,
      nowclipheight: this._nowclipdistance,
      optobject: opt
    }
  },
  
  //显示辅助面
  showClipPolygon ( bol, id ) {
    var objectnum = Object.getOwnPropertyNames( this.ClipCubeCollection ).length
    if ( objectnum > 0 ) {
      if ( id ) {
        this._clippolygonCollection[id].enabled = bol
      } else {
        for ( var keys in this._clippolygonCollection ) {
          this._clippolygonCollection[keys].enabled = bol
        }
      }
    } else {
      console.error( 'RuntimeError :', 'undefined ClipVolume' )
    }
  },
  
  //移除裁剪
  removeClipAll () {
    var objectnum = Object.getOwnPropertyNames( this.ClipCubeCollection ).length
    if ( objectnum > 0 ) {
      for ( var key in this.ClipCubeCollection ) {
        this.ClipCubeCollection[key].clipvolume.delete()
        this.ClipCubeCollection[key].entity.delete()
        delete this.ClipCubeCollection[key]
      }
      
      for ( var keys in this._clippolygonCollection ) {
        this._clippolygonCollection[keys].delete()
        delete this.ClipCubeCollection[keys]
      }
    }
  },
  /**
   * 根据id移除裁切体和辅助面
   * @param {*} id
   */
  removeClipById ( id ) {
    var objectnum = Object.getOwnPropertyNames( this.ClipCubeCollection ).length
    if ( objectnum > 0 ) {
      this.ClipCubeCollection[id].clipvolume.delete()
      this.ClipCubeCollection[id].entity.delete()
      delete this.ClipCubeCollection[id]
      
      this._clippolygonCollection[id].delete()
      delete this.ClipCubeCollection[id]
    }
  },
  //随机id ~ 工具
  _getentityid () {
    let d = new Date()
    let n = d.getTime() + Math.random()
    let nowid = n.toString( 32 )
    return nowid
  },
  /**
   * 底部裁剪
   */
  bottomClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error( 'RuntimeError :', 'An ClipVolume with id ' + opt.clipid + ' already exists in this collection.' )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour == undefined ? false : opt.contour
    this._nowclipdistance = opt.cdistance || this._nowclipdistance
    this._ClipEObject = opt.clipobject
    if ( opt.clipobject ) {
      let maxminopt = this.getTilesrectangle( this._ClipEObject )//最大最小
      let centerpoint = this._gettpointCenter( maxminopt.maxmin, opt.cdistance / 2 )//中心点
      //计算长宽 及角度
      let Coptwihean = this._getwidthheightangle( maxminopt.recposition, centerpoint )
      //生成裁切面
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        alpha: 0.2,
        center: centerpoint
      }
      this.addCPolygon3D( maxminopt.maxmin, Popt, 0.1 )
      let clipopt = {
        flag: 2,//裁切对象
        clipwidth: opt.clipwidth || Coptwihean.width,//宽度
        cliplength: opt.cliplength || Coptwihean.height,//长度
        clipheight: this._nowclipdistance,//高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ],//暂时不给
        Eclipid: opt.clipid,//
        cliptype: 'bottomClip'
      }
      this.createdClip( clipopt )
    } else {
      console.error( 'RuntimeError :', 'Clip Object is undefined' )
    }
  },
  /**
   * 顶部裁剪
   * @param {*} opt
   * @returns
   */
  topClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error( 'RuntimeError :', 'An ClipVolume with id ' + opt.clipid + ' already exists in this collection.' )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour == undefined ? false : opt.contour
    this._nowclipdistance = opt.cdistance || 1
    this._ClipEObject = opt.clipobject
    if ( opt.clipobject ) {
      var centerheight = ( this._maxclipaltitude - this._nowclipdistance ) / 2
      let maxminopt = this.getTilesrectangle( this._ClipEObject )//最大最小
      let centerpoint = this._gettpointCenter( maxminopt.maxmin, centerheight )//中心点
      //计算长宽 及角度
      let Coptwihean = this._getwidthheightangle( maxminopt.recposition, centerpoint )
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        alpha: 0.2,
        center: centerpoint
      }
      this.addCPolygon3D( maxminopt.maxmin, Popt, -0.1 )
      let clipopt = {
        flag: 2,//裁切对象
        clipwidth: opt.clipwidth || Coptwihean.width,//宽度
        cliplength: opt.cliplength || Coptwihean.height,//长度
        clipheight: ( centerheight - this._nowclipdistance ) * 2,//高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ],//暂时不给
        Eclipid: opt.clipid,//
        cliptype: 'topClip'
      }
      this.createdClip( clipopt )
    } else {
      console.error( 'RuntimeError :', 'Clip Object is undefined' )
    }
  },
  /**
   * 正东部裁剪
   * @param {*} opt
   * @returns
   */
  eastClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error( 'RuntimeError :', 'An ClipVolume with id ' + opt.clipid + ' already exists in this collection.' )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour == undefined ? false : opt.contour
    this._nowclipdistance = opt.cdistance || 1//当前裁剪距离
    this._ClipEObject = opt.clipobject//裁剪对象
    if ( opt.clipobject ) {
      let maxminopt = this.getTilesrectangle( this._ClipEObject )//最大最小
      //辅助 裁切面
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        pulygonheight: opt.pheight || 300,
        type: 'east'
      }
      var poobject = this.addDirPolygon3D( maxminopt.recposition, Popt, 0.1 )
      var nowheight = opt.clipheight || 300
      var centersquare = this._getcentersquare( poobject, nowheight )
      var newsquare = this._Vector3toCartesian3( centersquare.squareposition )
      let centerpoint = this._gettpointCenter( newsquare )//中心点
      let clipopt = {
        flag: 2,//裁切对象
        clipwidth: opt.clipwidth || 0.1,//宽度
        cliplength: opt.cliplength || centersquare.distance,//长度
        clipheight: nowheight,//高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ],//暂时不给
        Eclipid: opt.clipid,//
        cliptype: 'eastClip',
        polygonoopt: poobject
      }
      this.createdClip( clipopt )
    }
  },
  /**
   * 正南部裁剪
   * @param {*} opt
   * @returns
   */
  southClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error( 'RuntimeError :', 'An ClipVolume with id ' + opt.clipid + ' already exists in this collection.' )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour == undefined ? false : opt.contour//是否显示轮廓
    this._nowclipdistance = opt.cdistance || 1//当前裁剪距离
    this._ClipEObject = opt.clipobject//裁剪对象
    if ( opt.clipobject ) {
      let maxminopt = this.getTilesrectangle( this._ClipEObject )//最大最小
      //辅助 裁切面
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        pulygonheight: opt.pheight || 300,
        type: 'south'
      }
      var poobject = this.addDirPolygon3D( maxminopt.recposition, Popt, 0.1 )
      
      var nowheight = opt.clipheight || 300
      var centersquare = this._getcentersquare( poobject, nowheight )
      var newsquare = this._Vector3toCartesian3( centersquare.squareposition )
      let centerpoint = this._gettpointCenter( newsquare )//中心点
      let clipopt = {
        flag: 2,//裁切对象
        clipwidth: opt.clipwidth || centersquare.distance,//宽度
        cliplength: opt.cliplength || 0.1,//长度
        clipheight: nowheight,//高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ],//暂时不给
        Eclipid: opt.clipid,//
        cliptype: 'southClip',
        polygonoopt: poobject
      }
      this.createdClip( clipopt )
      
    }
  },
  /**
   * 正西部裁剪
   * @param {*} opt
   * @returns
   */
  westClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error( 'RuntimeError :', 'An ClipVolume with id ' + opt.clipid + ' already exists in this collection.' )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour == undefined ? false : opt.contour
    this._nowclipdistance = opt.cdistance || 1//当前裁剪距离
    this._ClipEObject = opt.clipobject//裁剪对象
    if ( opt.clipobject ) {
      let maxminopt = this.getTilesrectangle( this._ClipEObject )//最大最小
      //辅助 裁切面
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        pulygonheight: opt.pheight || 300,
        type: 'west'
      }
      var poobject = this.addDirPolygon3D( maxminopt.recposition, Popt, 0.1 )
      
      var nowheight = opt.clipheight || 300
      var centersquare = this._getcentersquare( poobject, nowheight )
      var newsquare = this._Vector3toCartesian3( centersquare.squareposition )
      let centerpoint = this._gettpointCenter( newsquare )//中心点
      let clipopt = {
        flag: 2,//裁切对象
        clipwidth: opt.clipwidth || 0.1,//宽度
        cliplength: opt.cliplength || centersquare.distance,//长度
        clipheight: nowheight,//高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ],//暂时不给
        Eclipid: opt.clipid,//
        cliptype: 'westClip',
        polygonoopt: poobject
      }
      this.createdClip( clipopt )
    }
  },
  /**
   * 正北部裁剪
   * @param {*} opt
   * @returns
   */
  northClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error( 'RuntimeError :', 'An ClipVolume with id ' + opt.clipid + ' already exists in this collection.' )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour == undefined ? false : opt.contour
    this._nowclipdistance = opt.cdistance || 1//当前裁剪距离
    this._ClipEObject = opt.clipobject//裁剪对象
    if ( opt.clipobject ) {
      let maxminopt = this.getTilesrectangle( this._ClipEObject )//最大最小
      //辅助 裁切面
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        pulygonheight: opt.pheight || 300,
        type: 'north'
      }
      var poobject = this.addDirPolygon3D( maxminopt.recposition, Popt, 0.1 )
      
      var nowheight = opt.clipheight || 300
      var centersquare = this._getcentersquare( poobject, nowheight )
      var newsquare = this._Vector3toCartesian3( centersquare.squareposition )
      let centerpoint = this._gettpointCenter( newsquare )//中心点
      let clipopt = {
        flag: 2,//裁切对象
        clipwidth: opt.clipwidth || centersquare.distance,//宽度
        cliplength: opt.cliplength || 0.1,//长度
        clipheight: nowheight,//高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ],//暂时不给
        Eclipid: opt.clipid,//
        cliptype: 'northClip',
        polygonoopt: poobject
      }
      this.createdClip( clipopt )
    }
  },
  /**
   *
   * @param { TilesetLayer } T 裁剪对象 模型之类
   * @returns 裁剪范围
   */
  getTilesrectangle ( T ) {
    if ( T ) {
      //   if (T instanceof SSmap.Tileset) {
      let positionrectangle = T.rectangle//矩阵
      let nowsouthwest = positionrectangle.southwest().toCartesian3().toVector3()
      let nownorthwest = positionrectangle.northwest().toCartesian3().toVector3()
      
      let nownortheast = positionrectangle.northeast().toCartesian3().toVector3()
      let nowsoutheast = positionrectangle.southeast().toCartesian3().toVector3()
      
      let maxposition = this._extendTodistance( nownortheast, nowsoutheast, this._cumdistance ).position
      let minposition = this._extendTodistance( nowsouthwest, nownorthwest, this._cumdistance ).position
      return {
        maxmin: [ maxposition.toCartesian3(), minposition.toCartesian3() ],
        recposition: {
          southwest: nowsouthwest,
          northwest: nownorthwest,
          northeast: nownortheast,
          southeast: nowsoutheast
        }
      }
      //   }
    }
  },
  /**
   * 延伸几米
   * @return newpoint 返回新的延伸坐标
   * @param {Vector3} startpoint  需要延伸的坐标
   * @param {Vector3} endpoint  作为方向的延伸坐标辅助
   * @param {Number} num  几米
   * @returns
   */
  _extendTodistance ( startpoint, endpoint, num ) {
    num = num || 1
    // if (!(startpoint instanceof SSmap.Vector3)) return;
    // if (!(endpoint instanceof SSmap.Vector3)) return;
    let normal = SSmap.Vector3.subtract( startpoint, endpoint ).normalize()
    if ( normal ) {
      let nownormal = SSmap.Vector3.create( normal.x * num, normal.y * num, normal.z * num )
      let nowposition = SSmap.Vector3.create( startpoint.x + nownormal.x, startpoint.y + nownormal.y, startpoint.z + nownormal.z )
      return {
        vector: normal,//向量
        position: nowposition.toCartographic()
      }
    } else {
      return null
    }
  },
  /**
   * @description 计算中心点
   * @param { list } points 笛卡尔坐标数组 Cartesian3
   * @param { Number } h 中心点初始高度
   * @return point
   */
  _gettpointCenter ( points, h ) {
    // if (!(points instanceof Array)) return;
    // if (!(points[0] instanceof SSmap.Cartesian3)) return;
    let PVX = Number.MAX_VALUE //x的最大值
    let PVY = Number.MAX_VALUE //y的最大值
    let PVZ = Number.MAX_VALUE //z的最大值
    let NVX = -Number.MAX_VALUE //-x的最大值
    let NVY = -Number.MAX_VALUE //-y的最大值
    let NVZ = -Number.MAX_VALUE //-z的最大值
    if ( points.length == 0 ) {
      console.error( '只有一个点，无法计算' )
    } else if ( points.length == 1 ) {
      console.error( '有两个点，无法计算' )
    } else {
      for ( let i = 0; i < points.length; i++ ) {
        if ( points[i].x < PVX ) {
          PVX = points[i].x
        }
        if ( points[i].y < PVY ) {
          PVY = points[i].y
        }
        if ( points[i].z < PVZ ) {
          PVZ = points[i].z
        }
        if ( points[i].x > NVX ) {
          NVX = points[i].x
        }
        if ( points[i].y > NVY ) {
          NVY = points[i].y
        }
        if ( points[i].z > NVZ ) {
          NVZ = points[i].z
        }
      }
      let l = SSmap.Vector3.create( ( NVX + PVX ) / 2, ( NVY + PVY ) / 2, ( NVZ + PVZ ) / 2 )
      if ( window.GlobalViewer.scene.globe ) {
        var position = l.toCartesian3().toCartographic().toDegrees()
        var nowh = position.height > 0 ? position.height : 0
        var newL = SSmap.Cartesian3.fromDegrees( position.longitude, position.latitude, h || nowh )
        return newL.toVector3()
      } else {
        return {
          lon: l.x,
          lat: l.y,
          height: l.z
        }
      }
    }
  },
  /**
   *
   * @param {Object} maxminposition
   * @param {Vector3} center
   * @returns
   */
  _getwidthheightangle ( maxminposition, center ) {
    // if (!(maxminposition.southwest instanceof SSmap.Vector3) && !(maxminposition.northwest instanceof SSmap.Vector3)
    // && !(maxminposition.northeast instanceof SSmap.Vector3) && !(maxminposition.southeast instanceof SSmap.Vector3))
    // return;
    let nowheight = maxminposition.southeast.distance( maxminposition.northeast ) + this._cumdistance
    let nowwidth = maxminposition.southeast.distance( maxminposition.southwest ) + this._cumdistance
    //中心点 最大坐标 的方位角度
    var one = center.toCartographic().toDegrees()
    var two = maxminposition.northeast.toCartographic().toDegrees()
    var pt1 = {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [ one.longitude, one.latitude, 0 ]
      }
    }
    var pt2 = {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [ two.longitude, two.latitude, 0 ]
      }
    }
    // var nowbearing = turf.rhumbBearing(pt1, pt2);//角度
    return {
      width: nowwidth,
      height: nowheight
      //   bearing: nowbearing,
    }
  },
  //生成裁切面 上下
  addCPolygon3D ( maxminposition, opt, num ) {
    var objectnum = Object.getOwnPropertyNames( this.ClipCubeCollection ).length
    if ( objectnum >= 8 ) {
      console.error( 'RangeError :', 'Maximum call Polygon3D value exceeded' )
      return
    }
    //相同id 不同重复创建
    if ( this.ClipCubeCollection[opt.polygonid] ) {
      console.error( 'RuntimeError :', 'An Polygon3D with id ' + opt.polygonid + ' already exists in this collection.' )
      return
    }
    opt = opt || {}
    let maxposition = maxminposition[0].toCartographic().toDegrees()
    let minposition = maxminposition[1].toCartographic().toDegrees()
    let PolygonArray = []
    let oneposition = SSmap.Cartesian3.fromDegrees( maxposition.longitude, maxposition.latitude, this._nowclipdistance + num )
    let twoposition = SSmap.Cartesian3.fromDegrees( maxposition.longitude, minposition.latitude, this._nowclipdistance + num )
    let threeposition = SSmap.Cartesian3.fromDegrees( minposition.longitude, minposition.latitude, this._nowclipdistance + num )
    let fourposition = SSmap.Cartesian3.fromDegrees( minposition.longitude, maxposition.latitude, this._nowclipdistance + num )
    PolygonArray.push( oneposition.toVector3() )
    PolygonArray.push( twoposition.toVector3() )
    PolygonArray.push( threeposition.toVector3() )
    PolygonArray.push( fourposition.toVector3() )
    PolygonArray.push( oneposition.toVector3() )
    let optp = {
      color: opt.color || '#FF0000', //边线颜色
      alpha: opt.alpha || 0.2, //边线颜色透明度
      pointArray: PolygonArray, //弧度数组类型
      name: 'Extrude' + opt.polygonid, //实体名称
      show: opt.isshow == undefined ? false : opt.isshow,//显示否
      center: opt.centerpoint,
      hnum: num,
      extrudeHeight: opt.pulygonheight || 0.1
    }
    console.log( optp, 'addCPolygon3D' )
    var polygon = this.ExtrudePolygonGraphics( optp )
    this._clippolygonCollection[opt.polygonid] = polygon
  },
  /**
   * 拉伸多边形 立体
   * @param {*} opt
   */
  ExtrudePolygonGraphics ( opt ) {
    opt = opt || {}
    //创建点
    var outer = new SSmap.Cartesian3Vector()
    opt.pointArray.forEach( ( item, index, array ) => {
      //笛卡尔坐标添加
      //   if (item instanceof SSmap.Vector3) {
      //     var ddd = item.toCartesian3();
      //     outer.push_back(item.toCartesian3());
      //   } else if (item instanceof SSmap.Cartesian3) {
      //     outer.push_back(item);
      //   }
      outer.push_back( item.toCartesian3() )
    } )
    var extrudeEntity = new SSmap.ExtrudeEntity()
    extrudeEntity.setOuter( outer )
    extrudeEntity.extrudeHeight = opt.extrudeHeight || 0.1
    extrudeEntity.color = this.colorToRGB( opt.color || '#FF0000', opt.alpha || 1.0 ) //颜色
    extrudeEntity.alpha = opt.alpha || 0.2//透明度
    extrudeEntity.create()
    var ent = extrudeEntity.createEntity()
    ent.enabled = opt.show
    window.GlobalViewer.scene.addEntity( ent )
    ent.objectName = opt.name || ''
    ent.attribute = opt || ''
    extrudeEntity.delete()
    outer.delete()
    return ent
  },
  //颜色16进制转rgb ~ 工具
  colorToRGB ( color, a ) {
    let color1, color2, color3
    color = '' + color
    if ( typeof color !== 'string' ) return
    if ( color.charAt( 0 ) == '#' ) {
      color = color.substring( 1 )
    }
    if ( color.length == 3 ) {
      color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2]
    }
    if ( /^[0-9a-fA-F]{6}$/.test( color ) ) {
      color1 = parseInt( color.substr( 0, 2 ), 16 )
      color2 = parseInt( color.substr( 2, 2 ), 16 )
      color3 = parseInt( color.substr( 4, 2 ), 16 )
      //return "rgb(" + color1 + "," + color2 + "," + color3 + ")";
      //return [color1, color2, color3, Math.round(Number(a) * 255)];
      return SSmap.Color.fromRgb( color1, color2, color3, Math.round( Number( a ) * 255 ) )
    }
  },
  /**
   * 更新裁剪海拔
   */
  setDistanceById ( id, clipdistance ) {
    var nowoldheight = this._nowclipdistance - clipdistance
    this._nowclipdistance = clipdistance
    if ( this.ClipCubeCollection[id] ) {
      let nowcliptype = this.ClipCubeCollection[id].type
      let lonlats = this.ClipCubeCollection[id].entity.transform.cartographic.toDegrees()
      let nowoptobject = this.ClipCubeCollection[id].optobject
      switch ( nowcliptype ) {
        case 'bottomClip':
          //底部裁剪
          if ( nowoptobject ) {
            this.ClipCubeCollection[id].optobject.clipheight = clipdistance
          }
          let width = nowoptobject.clipwidth || 100
          let length = nowoptobject.cliplength || 100
          this.ClipCubeCollection[id].clipvolume.size = SSmap.Vector3.create( width / 2, length / 2, clipdistance )
          this.ClipCubeCollection[id].entity.transform.cartographic = SSmap.Cartographic.fromDegrees( lonlats.longitude, lonlats.latitude, 0 ) //坐标
          if ( this._clippolygonCollection[id] ) {
            //面的海拔
            var lnum = this._clippolygonCollection[id].attribute.hnum || 0.1
            var nowEposition = this._clippolygonCollection[id].transform.cartographic.toDegrees()
            this._clippolygonCollection[id].transform.cartographic = SSmap.Cartographic.fromDegrees( nowEposition.longitude, nowEposition.latitude, nowEposition.height - nowoldheight )
          }
          break
        case 'topClip':
          //顶部裁剪
          if ( nowoptobject ) {
            this.ClipCubeCollection[id].optobject.clipheight = clipdistance
          }
          var centerheight = ( this._maxclipaltitude - clipdistance ) / 2
          let topwidth = nowoptobject.clipwidth || 100
          let toplength = nowoptobject.cliplength || 100
          this.ClipCubeCollection[id].clipvolume.size = SSmap.Vector3.create( topwidth / 2, toplength / 2, centerheight - clipdistance )
          this.ClipCubeCollection[id].entity.transform.cartographic = SSmap.Cartographic.fromDegrees( lonlats.longitude, lonlats.latitude, centerheight ) //坐标
          if ( this._clippolygonCollection[id] ) {
            //面的海拔
            var lnum = this._clippolygonCollection[id].attribute.hnum || -0.1
            var nowEposition = this._clippolygonCollection[id].transform.cartographic.toDegrees()
            this._clippolygonCollection[id].transform.cartographic = SSmap.Cartographic.fromDegrees( nowEposition.longitude, nowEposition.latitude, nowEposition.height - nowoldheight )
          }
          break
        case 'eastClip':
          var nowv = null
          if ( nowoptobject ) {
            nowv = nowoptobject.polygonoopt.vector
          }
          //尺寸
          let eastwidth = nowoptobject.clipwidth - ( nowoldheight / 2 )
          let noweastwidth = eastwidth < 0.1 ? 0.05 : eastwidth
          let eastlength = nowoptobject.cliplength / 2 || 100
          let eastheight = nowoptobject.clipheight / 2 || 200
          this.ClipCubeCollection[id].clipvolume.size = SSmap.Vector3.create( noweastwidth, eastlength, eastheight )
          this.ClipCubeCollection[id].optobject.clipwidth = noweastwidth
          //裁切体坐标
          let clipposition = this.ClipCubeCollection[id].entity.transform.cartographic.toCartesian3()
          var newnowoldheight = ( nowoldheight / 2 )
          if ( noweastwidth == 0.05 ) {
            newnowoldheight = nowoldheight
          }
          var newclipcartographic = this._getnewvectorposition( clipposition, nowv, newnowoldheight )
          this.ClipCubeCollection[id].entity.transform.cartographic = newclipcartographic
          //面
          if ( this._clippolygonCollection[id] ) {
            var nowEposition = this._clippolygonCollection[id].transform.cartographic.toCartesian3()
            var newcartographic = this._getnewvectorposition( nowEposition, nowv, nowoldheight )
            this._clippolygonCollection[id].transform.cartographic = newcartographic
          }
          break
        case 'southClip':
          var nowv = null
          if ( nowoptobject ) {
            nowv = nowoptobject.polygonoopt.vector
          }
          //尺寸
          let southwidth = nowoptobject.clipwidth / 2 || 100
          let southlength = nowoptobject.cliplength - ( nowoldheight / 2 )
          let nowsouthlength = southlength < 0.1 ? 0.05 : southlength
          let southheight = nowoptobject.clipheight / 2 || 200
          this.ClipCubeCollection[id].clipvolume.size = SSmap.Vector3.create( southwidth, nowsouthlength, southheight )
          this.ClipCubeCollection[id].optobject.cliplength = nowsouthlength
          //裁切体坐标
          let clippositions = this.ClipCubeCollection[id].entity.transform.cartographic.toCartesian3()
          let newnowsouthlength = ( nowoldheight / 2 )
          if ( nowsouthlength == 0.05 ) {
            newnowsouthlength = nowoldheight
          }
          var newclipcartographic = this._getnewvectorposition( clippositions, nowv, newnowsouthlength )
          this.ClipCubeCollection[id].entity.transform.cartographic = newclipcartographic
          //面
          if ( this._clippolygonCollection[id] ) {
            var nowEposition = this._clippolygonCollection[id].transform.cartographic.toCartesian3()
            var newcartographic = this._getnewvectorposition( nowEposition, nowv, nowoldheight )
            this._clippolygonCollection[id].transform.cartographic = newcartographic
          }
          break
        case 'westClip':
          var nowv = null
          if ( nowoptobject ) {
            nowv = nowoptobject.polygonoopt.vector
          }
          //尺寸
          let westwidth = nowoptobject.clipwidth - ( nowoldheight / 2 )
          let nowwestwidth = westwidth < 0.1 ? 0.05 : westwidth
          let westlength = nowoptobject.cliplength / 2 || 100
          let westheight = nowoptobject.clipheight / 2 || 200
          this.ClipCubeCollection[id].clipvolume.size = SSmap.Vector3.create( nowwestwidth, westlength, westheight )
          this.ClipCubeCollection[id].optobject.clipwidth = nowwestwidth
          //裁切体坐标
          let clippositionw = this.ClipCubeCollection[id].entity.transform.cartographic.toCartesian3()
          var newnowoldheight = ( nowoldheight / 2 )
          if ( nowwestwidth == 0.05 ) {
            newnowoldheight = nowoldheight
          }
          var newclipcartographic = this._getnewvectorposition( clippositionw, nowv, newnowoldheight )
          this.ClipCubeCollection[id].entity.transform.cartographic = newclipcartographic
          
          //面
          if ( this._clippolygonCollection[id] ) {
            var nowEposition = this._clippolygonCollection[id].transform.cartographic.toCartesian3()
            var newcartographic = this._getnewvectorposition( nowEposition, nowv, nowoldheight )
            this._clippolygonCollection[id].transform.cartographic = newcartographic
          }
          break
        case 'northClip':
          var nowv = null
          if ( nowoptobject ) {
            nowv = nowoptobject.polygonoopt.vector
          }
          //尺寸
          let northwidth = nowoptobject.clipwidth / 2 || 100
          let northlength = nowoptobject.cliplength - ( nowoldheight / 2 )
          let nownorthlength = northlength < 0.1 ? 0.05 : northlength
          let northheight = nowoptobject.clipheight / 2 || 200
          this.ClipCubeCollection[id].clipvolume.size = SSmap.Vector3.create( northwidth, nownorthlength, northheight )
          this.ClipCubeCollection[id].optobject.cliplength = nownorthlength
          //裁切体坐标
          let clippositionn = this.ClipCubeCollection[id].entity.transform.cartographic.toCartesian3()
          let newnownorthlength = ( nowoldheight / 2 )
          if ( nownorthlength == 0.05 ) {
            newnownorthlength = nowoldheight
          }
          var newclipcartographic = this._getnewvectorposition( clippositionn, nowv, newnownorthlength )
          this.ClipCubeCollection[id].entity.transform.cartographic = newclipcartographic
          
          //面
          if ( this._clippolygonCollection[id] ) {
            var nowEposition = this._clippolygonCollection[id].transform.cartographic.toCartesian3()
            var newcartographic = this._getnewvectorposition( nowEposition, nowv, nowoldheight )
            this._clippolygonCollection[id].transform.cartographic = newcartographic
          }
          break
      }
    } else {
      console.error( 'RuntimeError :', 'An ClipVolume with id ' + id + ' no exists in this collection.' )
    }
  },
  //生成裁切面 辅助 东南西北 四个方向
  /**
   *
   * @param {*} recposition 模型四个角坐标
   * @param {*} opt 属性
   * @param {*} num 距离
   * @returns
   */
  addDirPolygon3D ( recposition, opt, num ) {
    var objectnum = Object.getOwnPropertyNames( this.ClipCubeCollection ).length
    if ( objectnum >= 8 ) {
      console.error( 'RangeError :', 'Maximum call Polygon3D value exceeded' )
      return
    }
    //相同id 不同重复创建
    if ( this.ClipCubeCollection[opt.polygonid] ) {
      console.error( 'RuntimeError :', 'An Polygon3D with id ' + opt.polygonid + ' already exists in this collection.' )
      return
    }
    opt = opt || {}
    //计算向量
    let PolygonObject = this._getvectorbypoint( recposition, opt.type, num )
    
    let optp = {
      color: opt.color || '#FF0000', //边线颜色
      alpha: opt.alpha || 0.2, //边线颜色透明度
      pointArray: PolygonObject.polygonarray, //弧度数组类型
      name: 'Extrude' + opt.polygonid, //实体名称
      show: opt.isshow == undefined ? false : opt.isshow,//显示否
      center: opt.centerpoint,
      extrudeHeight: opt.pulygonheight || 300
    }
    console.log( optp, 'addDirPolygon3D' )
    var polygon = this.ExtrudePolygonGraphics( optp )
    this._clippolygonCollection[opt.polygonid] = polygon
    return PolygonObject
  },
  //计算向量
  _getvectorbypoint ( nowrecposition, type, num ) {
    var returndata = {}
    let PolygonArray = []
    switch ( type ) {
      case 'east':
        var newextend = this._extendTodistance( nowrecposition.northeast, nowrecposition.northwest, -num )
        var wposition1 = newextend.position
        var wposition2 = this._extendTodistance( nowrecposition.southeast, nowrecposition.southwest, -num ).position
        PolygonArray.push( nowrecposition.northeast )
        PolygonArray.push( wposition1.toCartesian3().toVector3() )
        PolygonArray.push( wposition2.toCartesian3().toVector3() )
        PolygonArray.push( nowrecposition.southeast )
        returndata.pointList = []
        var wposition12 = this._extendTodistance( nowrecposition.northeast, nowrecposition.northwest, num * 2 ).position
        var wposition22 = this._extendTodistance( nowrecposition.southeast, nowrecposition.southwest, num * 2 ).position
        returndata.pointList.push( wposition12.toCartesian3().toVector3() )
        returndata.pointList.push( wposition22.toCartesian3().toVector3() )
        returndata.vector = newextend.vector
        returndata.polygonarray = PolygonArray
        break
      case 'west':
        var newextend = this._extendTodistance( nowrecposition.northwest, nowrecposition.northeast, num )
        var wposition1 = newextend.position
        var wposition2 = this._extendTodistance( nowrecposition.southwest, nowrecposition.southeast, num ).position
        PolygonArray.push( nowrecposition.northwest )
        PolygonArray.push( wposition1.toCartesian3().toVector3() )
        PolygonArray.push( wposition2.toCartesian3().toVector3() )
        PolygonArray.push( nowrecposition.southwest )
        returndata.pointList = []
        var wposition12 = this._extendTodistance( nowrecposition.northwest, nowrecposition.northeast, num * 2 ).position
        var wposition22 = this._extendTodistance( nowrecposition.southwest, nowrecposition.southeast, num * 2 ).position
        returndata.pointList.push( wposition12.toCartesian3().toVector3() )
        returndata.pointList.push( wposition22.toCartesian3().toVector3() )
        returndata.vector = newextend.vector
        returndata.polygonarray = PolygonArray
        break
      case 'south':
        var newextend = this._extendTodistance( nowrecposition.southeast, nowrecposition.northeast, num )
        var wposition1 = newextend.position
        var wposition2 = this._extendTodistance( nowrecposition.southwest, nowrecposition.northwest, num ).position
        PolygonArray.push( nowrecposition.southeast )
        PolygonArray.push( wposition1.toCartesian3().toVector3() )
        PolygonArray.push( wposition2.toCartesian3().toVector3() )
        PolygonArray.push( nowrecposition.southwest )
        
        returndata.pointList = []
        var wposition12 = this._extendTodistance( nowrecposition.southeast, nowrecposition.northeast, num * 2 ).position
        var wposition22 = this._extendTodistance( nowrecposition.southwest, nowrecposition.northwest, num * 2 ).position
        returndata.pointList.push( wposition12.toCartesian3().toVector3() )
        returndata.pointList.push( wposition22.toCartesian3().toVector3() )
        returndata.vector = newextend.vector
        returndata.polygonarray = PolygonArray
        break
      case 'north':
        var newextend = this._extendTodistance( nowrecposition.northeast, nowrecposition.southeast, -num )
        var wposition1 = newextend.position
        var wposition2 = this._extendTodistance( nowrecposition.northwest, nowrecposition.southwest, -num ).position
        PolygonArray.push( nowrecposition.northeast )
        PolygonArray.push( wposition1.toCartesian3().toVector3() )
        PolygonArray.push( wposition2.toCartesian3().toVector3() )
        PolygonArray.push( nowrecposition.northwest )
        
        returndata.pointList = []
        var wposition12 = this._extendTodistance( nowrecposition.northeast, nowrecposition.southeast, num * 2 ).position
        var wposition22 = this._extendTodistance( nowrecposition.northwest, nowrecposition.southwest, num * 2 ).position
        returndata.pointList.push( wposition12.toCartesian3().toVector3() )
        returndata.pointList.push( wposition22.toCartesian3().toVector3() )
        returndata.vector = newextend.vector
        returndata.polygonarray = PolygonArray
        break
      default:
        //默认 东边
        var newextend = this._extendTodistance( nowrecposition.northeast, nowrecposition.northwest, -0.1 )
        var wposition1 = newextend.position
        var wposition2 = this._extendTodistance( nowrecposition.southeast, nowrecposition.southwest, -0.1 ).position
        PolygonArray.push( nowrecposition.northeast )
        PolygonArray.push( wposition1.toCartesian3().toVector3() )
        PolygonArray.push( wposition2.toCartesian3().toVector3() )
        PolygonArray.push( nowrecposition.southeast )
        
        returndata.pointList = []
        var wposition12 = this._extendTodistance( nowrecposition.northeast, nowrecposition.northwest, -0.1 * 2 ).position
        var wposition22 = this._extendTodistance( nowrecposition.southeast, nowrecposition.southwest, -0.1 * 2 ).position
        returndata.pointList.push( wposition12.toCartesian3().toVector3() )
        returndata.pointList.push( wposition22.toCartesian3().toVector3() )
        returndata.vector = newextend.vector
        returndata.polygonarray = PolygonArray
        break
    }
    return returndata
  },
  //四方向 的中心点
  _getcentersquare ( nowpoobject, nowheight ) {
    var squareobj = {}
    if ( nowpoobject.pointList.length == 2 ) {
      var points = nowpoobject.pointList
      squareobj.distance = points[0].distance( points[1] )
      squareobj.squareposition = []
      for ( var i = 0; i < points.length; i++ ) {
        var point = points[i]
        var degress = point.toCartesian3().toCartographic().toDegrees()
        squareobj.squareposition.push( point.toCartesian3() )
        var newpoint = SSmap.Cartesian3.fromDegrees( degress.longitude, degress.latitude, nowheight )
        squareobj.squareposition.push( newpoint )
      }
    }
    return squareobj
  },
  _Vector3toCartesian3 ( points ) {
    var newpoints = []
    for ( var i = 0; i < points.length; i++ ) {
      var point = points[i]
      //   if (point instanceof SSmap.Vector3) {
      //     newpoints.push(point.toCartesian3());
      //   } else {
      //     newpoints.push(point);
      //   }
      newpoints.push( point )
    }
    return newpoints
  },
  _getnewvectorposition ( startpoint, normal, num ) {
    // if (startpoint instanceof SSmap.Cartographic) {
    //   startpoint = startpoint.toCartesian3();
    // }
    if ( normal ) {
      let nownormal = SSmap.Vector3.create( normal.x * num, normal.y * num, normal.z * num )
      let nowposition = SSmap.Vector3.create( startpoint.x + nownormal.x, startpoint.y + nownormal.y, startpoint.z + nownormal.z )
      return nowposition.toCartographic()
    }
  }
}